package org.example.business.endpoint.http.event.message;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Data
public class HttpRsp {

    private Map<DataType, Map<String, HttpData>> dataMap = new ConcurrentHashMap<>();

    public int getStatus(){
        return getHttpDataValue(DataType.STATUS, DataType.STATUS.name(), 200);

    }

    public byte[] getBody(){
        return getHttpDataValue(DataType.BODY, DataType.BODY.name(), new byte[]{});

    }

    public Map<String, String> getHeaders(){

        Map<String, HttpData> httpDataMap = getHttpDataMap(DataType.HEADER);

        Map<String, String> headerMap = new HashMap<>();

        httpDataMap.forEach((key, value)->{
            headerMap.put(key, (String)value.getData());

        });

        return headerMap;

    }

    public void setStatus(int status){
        putHttpDataValue(DataType.STATUS, DataType.STATUS.name(), status);

    }

    public void addHeader(String key, String value){
        putHttpDataValue(DataType.HEADER, key, value);

    }

    public void setBody(byte[] bodyBytes){
        putHttpDataValue(DataType.BODY, DataType.BODY.name(), bodyBytes);

    }

    @Override
    public String toString(){

        StringBuilder builder = new StringBuilder();

        builder.append("HttpRsp(");

        builder.append("status: ").append(getStatus());

        builder.append(")");

        return builder.toString();

    }

    private <T> T getHttpDataValue(DataType type, String key, T fallback){

        HttpData<T> httpData = getHttpDataMap(type).get(key);

        if(null == httpData){
            return fallback;
        }

        return httpData.getData();

    }

    private <T> void putHttpDataValue(DataType type, String key, T value){
        getHttpDataMap(type).put(key, new HttpData<T>(key, value));

    }

    private Map<String, HttpData> getHttpDataMap(DataType type){
        Map<String, HttpData> httpDataMap = dataMap.get(type);

        if(null == httpDataMap){
            httpDataMap = new ConcurrentHashMap<>();
            dataMap.put(type, httpDataMap);

        }

        return httpDataMap;

    }

}
